/*
 * Copyright 2009 Cedric Priscal
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.serialport.sample;

import static utils.BikeCommandUtil.hexStringToByteArray;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.KeyEvent;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import utils.BikeCommandUtil;
import utils.SaveHexStringToFile;

/**
 * 显示一个控制台界面
 * 用户可以在界面上输入数据并通过串口发送，同时也可以接收串口数据并显示在界面上。
 */
public class ConsoleActivity extends SerialPortActivity {

    // 用于显示接收到的数据的 EditText 控件。
    EditText mReception;

    private String TAG = "ConsoleActivity";
    private StringBuilder receivedData = new StringBuilder(); // 用于存储接收到的数据
    private StringBuilder receivedDataBuffer = new StringBuilder();
    private Handler handler = new Handler(Looper.getMainLooper());
    private Runnable outputRunnable;
    private static final int OUTPUT_DELAY = 500; // 500ms delay to wait for data to be completely received
    private static final String SAVE_FILE_NAME = "save.bin";

    // 参数时间
    private double totalDistance = 0.0;
    private double totalPower = 0.0;
    private double totalEnergy = 0.0;
    private double totalOutput = 0.0;
    private int totalRPM = 0;
    private int rpmTimeCount = 0;
    private double maxRPM = 0;
    private static long startTime = 0; // 记录开始时间
    private static long timeGap = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.e(TAG, "ConsoleActivity is initialized");
        setContentView(R.layout.console);

        //setTitle("Loopback test");
        mReception = (EditText) findViewById(R.id.EditTextReception);
        EditText Emission = (EditText) findViewById(R.id.EditTextEmission);

        if (mReception == null) {
            Log.e("ConsoleActivity", "mReception is null");
        } else {
            Log.e("ConsoleActivity", "mReception initialized");
        }

        if (Emission == null) {
            Log.e("ConsoleActivity", "Emission is null");
        } else {
            Log.e("ConsoleActivity", "Emission initialized");
        }
        Emission.setOnEditorActionListener(new OnEditorActionListener() {
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                Log.e("ConsoleActivity", "Editor action detected");
                int i;
                CharSequence t = v.getText();
                char[] text = new char[t.length()];
                for (i = 0; i < t.length(); i++) {
                    text[i] = t.charAt(i);
                }
                try {
                    synchronized (mOutputStream) {
                        // 检查 mOutputStream 是否已初始化
                        if (mOutputStream != null) {
                            mOutputStream.write(new String(text).getBytes());
                            Log.e("ConsoleActivity", "Sent: " + new String(text));
                            mOutputStream.write('\n');
                        } else {
                            Log.e("ConsoleActivity", "Output stream is not initialized");
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return false;
            }
        });
    }

    private StringBuilder res = new StringBuilder();

    @Override
    protected void onDataReceived(final byte[] buffer, final int size) {
        runOnUiThread(new Runnable() {
            public void run() {
                if (mReception != null) {
                    // 将接收到的数据追加到 mReception 组件中
                    // Log.e("ConsoleActivity", "Received: " + new String(buffer, 0, size));
                    StringBuilder hexStringBuilder = new StringBuilder();
                    for (int i = 0; i < size; i++) {
                        String hex = Integer.toHexString(buffer[i] & 0xFF);
                        if (hex.length() == 1) {
                            hexStringBuilder.append('0'); // 保证每个字节显示为两位
                        }
                        hexStringBuilder.append(hex);
                    }

                    String receivedString = hexStringBuilder.toString();

                    // 将接收到的字符串转换为字节数组
                    byte[] byteArray = hexStringToByteArray(receivedString);
                    byte[] data = Arrays.copyOfRange(byteArray, 4, byteArray.length - 2);

                    // 调用 parse 函数处理字节数组
                    List<Integer> parsedValues = BikeCommandUtil.parse(data);

                    // 将接收到的字符串和解析后的结果显示在 mReception 中
                    mReception.append("Received: " + receivedString + "\n");
                    mReception.append("Parsed Values: " + parsedValues.toString() + "\n");

                    if (startTime == 0) {
                        startTime = System.currentTimeMillis();
                    }

                    if (startTime == 0) {
                        startTime = System.currentTimeMillis();
                    }

                    // 解析返回的值
                    double instantaneousSpeed = parsedValues.get(0) * 0.01; // Km/h
                    double instantaneousCadence = parsedValues.get(1) * 0.5; // RPM
                    int resistanceLevel = parsedValues.get(2); // 阻力级别
                    double instantaneousPower = parsedValues.get(3); // Watt

                    // 更新总RPM和RPM时间计数
                    totalRPM += instantaneousCadence;
                    rpmTimeCount++;

                    // 计算每秒的距离（米）
                    double distanceInSecond = instantaneousSpeed / 3600 * 1000;
                    totalDistance += distanceInSecond;

                    // 更新总功率
                    totalPower += instantaneousPower;

                    // 计算每秒能量输出
                    double output = instantaneousPower * 1 / 1000;
                    totalOutput += output;

                    // 计算能量 (kcal)
                    double energy = output / 4.186 / 0.22;
                    totalEnergy += energy;

                    // 计算最大RPM
                    if (instantaneousCadence > maxRPM) {
                        maxRPM = instantaneousCadence;
                    }

                    // 计算当前活动时间
                    // long elapsedTime = System.currentTimeMillis() - startTime;
                    timeGap += 1000;
                    long elapsedTime = timeGap;
                    // elapsedTime += System.currentTimeMillis() - startTime;
                    double activeTimeInHours = elapsedTime / 3600000.0; // 转换为小时

                    // 计算平均速度 (Km/h)
                    double avgSpeed = totalDistance / (activeTimeInHours * 1000);

                    // 计算平均踏频 (RPM)
                    double avgCadence = totalRPM / rpmTimeCount;

                    // 计算平均功率 (Watt)
                    double avgPower = totalPower / (elapsedTime / 1000.0); // 转换为秒

                    // 计算每小时能量 (kcal/h)
                    double energyPerHour = totalEnergy / activeTimeInHours;

                    // 计算每小时输出 (KJ/h)
                    double outputPerHour = totalOutput / activeTimeInHours;

                    mReception.append("Instantaneous Speed: " + instantaneousSpeed + " Km/h\n");
                    mReception.append("Avg. Speed: " + avgSpeed + " Km/h\n");
                    mReception.append("Instantaneous Cadence: " + instantaneousCadence + " RPM\n");
                    mReception.append("Avg. Cadence: " + avgCadence + " RPM\n");
                    mReception.append("Distance in Second: " + distanceInSecond + " meters\n");
                    mReception.append("Total Distance: " + totalDistance + " meters\n");
                    mReception.append("Resistance Level: " + resistanceLevel + "\n");
                    mReception.append("Instantaneous Power: " + instantaneousPower + " Watt\n");
                    mReception.append("Total Power: " + totalPower + " Watt\n");
                    mReception.append("Avg. Power: " + avgPower + " Watt\n");
                    mReception.append("Energy: " + energy + " kcal\n");
                    mReception.append("Total Energy: " + totalEnergy + " kcal\n");
                    mReception.append("Energy Per Hour: " + energyPerHour + " kcal/h\n");
                    mReception.append("Output Per Hour: " + outputPerHour + " kcal\n");
                    mReception.append("Output: " + output + " KJ\n");
                    mReception.append("Total Output: " + totalOutput + " KJ\n");
                    mReception.append("Max RPM: " + maxRPM + " RPM\n");
                    //mReception.append("\n");


                    // 保存数据到save.bin中去
                    /*byte[] byteArr = new byte[128];
                    int offset = 0;

                    byte[] bytes = ByteBuffer.allocate(4).putDouble(instantaneousSpeed).array();
                    System.arraycopy(bytes, 0, byteArr, offset, 4);
                    offset += 4;

                    bytes = ByteBuffer.allocate(4).putDouble(instantaneousCadence).array();
                    System.arraycopy(bytes, 0, byteArr, offset, 4);
                    offset += 4;

                    bytes = ByteBuffer.allocate(4).putInt(resistanceLevel).array();
                    System.arraycopy(bytes, 0, byteArr, offset, 4);
                    offset += 4;

                    bytes = ByteBuffer.allocate(4).putDouble(instantaneousPower).array();
                    System.arraycopy(bytes, 0, byteArr, offset, 4);
                    offset += 4;*/

                    /*// 获取外部存储根目录
                    File externalStorage = Environment.getExternalStorageDirectory();

                    // 创建应用程序专用的子目录
                    File appDir = new File(externalStorage, "com.example.myapp");
                    if (!appDir.exists()) {
                        appDir.mkdirs();
                    }

                    // 获取保存数据的目录路径
                    String saveDir = appDir.getAbsolutePath();

                    // 创建保存文件
                    File saveFile = new File(saveDir, SAVE_FILE_NAME);

                    try {
                        // 将数据写入文件
                        FileOutputStream fos = new FileOutputStream(saveFile);
                        fos.write(byteArr);
                        fos.flush();
                        fos.close();

                        // 打印保存成功日志
                        Log.i(TAG, "SaveData: " + saveFile.getAbsolutePath());
                    } catch (IOException e) {
                        // 打印保存失败日志
                        Log.e(TAG, "Failed to save data: " + e.getMessage());
                    }*/

                    // Reception.append(byteArr.toString() + "\n");

                    // 将 double 转换为 float
                    float mInstantaneousSpeed = (float)instantaneousSpeed;
                    float mAvgSpeed = (float)avgSpeed;

                    float mInstantaneousCadence = (float) instantaneousCadence;
                    float mAvgCadence = (float)avgCadence;

                    float mDistanceInSecond = (float)distanceInSecond;
                    float mTotalDistance = (float) totalDistance;

                    float mResistanceLevel = (float)resistanceLevel;

                    float mInstantaneousPower = (float) instantaneousPower;
                    float mTotalPower = (float) totalPower;
                    float mAvgPower = (float)avgPower;

                    float mEnergy = (float)energy;
                    float mTotalEnergy = (float) totalEnergy;
                    float mEnergyPerHour = (float) energyPerHour;

                    float mOutputPerHour = (float) outputPerHour;
                    float mOutput = (float) output;
                    float mTotalOutput = (float) totalOutput;

                    float mMaxRPM = (float) maxRPM;


                    // 创建一个字节缓冲区来存储这些数据
                    ByteBuffer buffer = ByteBuffer.allocate(68); // 4个float + 1个int = 16字节

                    // 将数据放入缓冲区
                    buffer.putFloat(mInstantaneousSpeed);
                    buffer.putFloat(mAvgSpeed);

                    buffer.putFloat(mInstantaneousCadence);
                    buffer.putFloat(mAvgCadence);

                    buffer.putFloat(mDistanceInSecond);
                    buffer.putFloat(mTotalDistance);

                    buffer.putFloat(mResistanceLevel);

                    buffer.putFloat(mInstantaneousPower);
                    buffer.putFloat(mTotalPower);
                    buffer.putFloat(mAvgPower);

                    buffer.putFloat(mEnergy);
                    buffer.putFloat(mTotalEnergy);
                    buffer.putFloat(mEnergyPerHour);

                    buffer.putFloat(mOutputPerHour);
                    buffer.putFloat(mOutput);
                    buffer.putFloat(mTotalOutput);

                    buffer.putFloat(mMaxRPM);

                    // 转换为字节数组
                    byte[] byteRes = buffer.array();
                    StringBuilder sb = new StringBuilder();
                    int number = 0;
                    for (byte b : byteRes) {
                        sb.append(String.format("%02X", b));
                        if (number % 2 == 1) {
                            sb.append(" ");
                        }
                        number ++;
                    }
                    sb.append("\n");

                    res.append(sb);

                    mReception.append(sb.toString());
                    mReception.append("\n");

                }
            }
        });

        // 保存到文件
        SaveHexStringToFile.saveHexStringToFile(this, res.toString());
    }

    // 暂停时重置参数
    private void ResetSomeDataWhenStopBiking(){
//        instantaneousPower = 0;
//        instantaneousCadence = 0;
//        instantaneousSpeed = 0;
//        currentStrokeOutput = 0;
    }
}
